<template>
  <!-- 控制栏容器 -->
  <el-form inline class="control-bar">
    <el-form-item label="Level">
      <el-select v-model="selectedLevel" placeholder="请选择层级" style="width: 150px">
        <el-option v-for="level in levels" :key="level" :label="`${level} hPa`" :value="level" />
      </el-select>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="loadData">应用</el-button>
    </el-form-item>
  </el-form>

  <el-card class="weather-map" shadow="hover">
    <template #header>
      <div class="header-container">
        <div class="header-title">
          <el-icon>
            <Sunny />
          </el-icon>
          <span>Geopotential 分布图</span>
        </div>
        <div class="header-subtitle">
          <el-tag type="info" effect="plain">层级: {{ levelName }} hPa</el-tag>
          <el-tag type="warning" effect="plain">预报时效: +{{ forecastTime }}小时</el-tag>
          <el-tag type="success" effect="plain">有效时间: {{ validTime }}</el-tag>
        </div>
      </div>
    </template>

    <div v-loading="loading" element-loading-text="正在渲染Geopotential 分布图...">
      <v-chart ref="chartRef" :option="chartOption" :autoresize="true" :onEvents="chartEvents"
        style="height: 600px; width: 100%;" />
    </div>
  </el-card>
</template>

<script>
import { ref, onMounted, defineComponent } from 'vue'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import {
  TitleComponent,
  VisualMapComponent,
  TooltipComponent,
  GeoComponent
} from 'echarts/components'
import VChart from 'vue-echarts'
import { ElCard, ElTag } from 'element-plus'
import { Sunny } from '@element-plus/icons-vue'
// import * as echarts from 'echarts';
// import worldData from '/src/world.json';
// echarts.registerMap('world', worldData);

use([
  CanvasRenderer,
  TitleComponent,
  VisualMapComponent,
  TooltipComponent,
  GeoComponent
])

export default defineComponent({
  name: 'WeatherMap',
  components: {
    VChart,
    ElCard,
    ElTag,
    Sunny
  },
  setup() {
    const forecastTime = ref(null)
    const validTime = ref('')
    const levelName = ref('')
    const loading = ref(true);
    const error = ref(null);
    const selectedLevel = ref(500);
    const levels = ref([]);
    const chartOption = ref(null);

    const processData = (Data) => {
      const seriesData = Data['Values'];

      const pressures = seriesData.map(d => d[2]);
      const minPressure = Math.min(...pressures);
      const maxPressure = Math.max(...pressures);

      // 设置元信息
      forecastTime.value = Data['Forecast Time'] || null
      validTime.value = Data['Valid Date'] || ''
      levelName.value = Data['Level'] || selectedLevel.value

      chartOption.value = {
        visualMap: {
          min: minPressure,
          max: maxPressure,
          left: 'center',
          top: 'bottom',
          text: ['m**2'],
          calculable: true,
          orient: 'horizontal',
          inRange: {
            color: [
              '#313695', '#4575b4', '#74add1', '#abd9e9',
              '#e0f3f8', '#ffffbf', '#fee090', '#fdae61',
              '#f46d43', '#d73027', '#a50026'
            ]
          }
        },
        geo: [{
          map: 'world',
          roam: true,
          // projection: { type: 'mercator', rotate: [30, -15, 0] },
          zlevel: 2,
          silent: false,
          itemStyle: {
            areaColor: 'transparent',
            borderColor: '#c0c4cc',
            borderWidth: 1
          }
        }],
        series: [{
          name: '气压点',
          type: 'scatter',
          coordinateSystem: 'geo',
          geoIndex: 0,
          data: seriesData,
          symbolSize: 6,
          itemStyle: { opacity: 0.6 }
        }]
      };
    };

    const loadLevels = async () => {
      try {
        const response = await fetch('/data/asset/Geopotential.json');
        if (!response.ok) throw new Error(`请求失败，状态码：${response.status}`);
        const data = await response.json();

        const rawLevels = data.levels || data.Levels || data["Level"] || [];
        levels.value = rawLevels.filter(Number.isInteger).sort((a, b) => a - b);

        const targetLevel = levels.value.find(l => l === 150);
        selectedLevel.value = targetLevel || (levels.value.length > 0 ? levels.value[0] : null);

        if (!targetLevel && levels.value.length > 0) {
          console.warn('150 hPa数据不可用，使用默认层级:', selectedLevel.value);
        }
      } catch (err) {
        error.value = `层级加载失败: ${err.message}`;
      }
    };

    const loadData = async () => {
      try {
        loading.value = true;
        error.value = null;

        if (!selectedLevel.value) {
          throw new Error('请选择有效层级');
        }

        const fileName = `/data/asset/Geopotential/Geopotential ${selectedLevel.value} hPa.json`;
        const response = await fetch(`${fileName}`);
        if (!response.ok) throw new Error(`请求失败，状态码：${response.status}`);
        console.log(response);
        console.log(fileName);
        const Data = await response.json();
        processData(Data);
      } catch (err) {
        error.value = `数据加载失败: ${err.message}`;
        console.error('请求错误:', err);
      } finally {
        loading.value = false;
      }
    };

    onMounted(async () => {
      await loadLevels();
      if (selectedLevel.value !== null && !error.value) {
        await loadData();
      } else {
        loading.value = false;
        error.value = error.value || '请先选择有效层级';
      }
    });

    return {
      chartOption,
      loading,
      error,
      selectedLevel,
      levels,
      loadData,
      // 关键部分：暴露这些变量
      forecastTime,
      validTime,
      levelName
    };
  },
  props: {
    configUrl: {
      type: String,
      default: '/data/asset/Geopotential/Geopotential 500 hPa.json'
    }
  },
  data() {
    return {
    }
  },
  computed: {
    chartEvents() {
      return {
        georoam: this.handleGeoRoam
      }
    }
  },
  mounted() {
    this.loadConfig()
  },
  methods: {
    async loadConfig() {
      const resp = await fetch(this.configUrl);
      const config = await resp.json();
      const seriesData = config['Values']
        .map(item => {
          const lon = this.normalizeLongitude(item[0]);
          const lat = this.clampLatitude(item[1]);
          return [lon, lat, item[2]];
        });

      const pressures = seriesData.map(d => d[2]);
      const minPressure = Math.min(...pressures);
      const maxPressure = Math.max(...pressures);

      this.chartOption = {
        visualMap: {
          min: minPressure,
          max: maxPressure,
          left: 'center',
          top: 'bottom',
          text: ['Pa'],
          calculable: true,
          orient: 'horizontal',
          inRange: {
            color: [
              '#313695', '#4575b4', '#74add1', '#abd9e9',
              '#e0f3f8', '#ffffbf', '#fee090', '#fdae61',
              '#f46d43', '#d73027', '#a50026'
            ]
          }
        },
        geo: [{
          map: 'world',
          roam: true,
          // projection: { type: 'mercator', rotate: [30, -15, 0] },
          zlevel: 2,
          silent: false,
          itemStyle: {
            areaColor: 'transparent',
            borderColor: '#c0c4cc',
            borderWidth: 1
          }
        }],
        series: [{
          name: '气压点',
          type: 'scatter',
          coordinateSystem: 'geo',
          geoIndex: 0,
          data: seriesData,
          symbolSize: 6,
          itemStyle: { opacity: 0.6 }
        }]
      };
    },
    handleGeoRoam(params) {
      const chart = this.$refs.chartRef.getEchartsInstance()
      const geo0 = chart.getModel().getComponent('geo', 0)
      const center = geo0.get('center')
      const zoom = geo0.get('zoom')
      chart.setOption({
        geo: { 1: { center, zoom } }
      }, false, false)
    },
    normalizeLongitude(lon) {
      while (lon < -180) lon += 360
      while (lon > 180) lon -= 360
      return lon
    },
    clampLatitude(lat) {
      return Math.min(Math.max(lat, -90), 90)
    }
  }

})
</script>

<style lang="scss" scoped>
.weather-map {
  background: var(--el-color-white);
  padding: 16px;
  border-radius: var(--el-border-radius-base);
}

.header-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-title {
  display: flex;
  align-items: center;
  font-size: 18px;
  font-weight: 500;
}

.header-title .el-icon {
  margin-right: 8px;
  font-size: 20px;
}

.header-subtitle {
  display: flex;
  gap: 8px;
}
</style>
